package com.link.play.fit.ai.ui.main.foodDatabase

import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.gson.Gson
import com.link.play.fit.ai.R
import com.link.play.fit.ai.base.BaseActivity
import com.link.play.fit.ai.base.goToAc
import com.link.play.fit.ai.base.goToAcForResult
import com.link.play.fit.ai.bean.CalendarStatusData
import com.link.play.fit.ai.bean.CollectFoodInfoData
import com.link.play.fit.ai.bean.FoodInfoBean
import com.link.play.fit.ai.bean.InfoIngredientsBean
import com.link.play.fit.ai.bean.ServingTypeBean
import com.link.play.fit.ai.bean.build
import com.link.play.fit.ai.bean.deepCopy
import com.link.play.fit.ai.bean.toRecentlyEatenData
import com.link.play.fit.ai.databinding.AcFoodEditBinding
import com.link.play.fit.ai.databinding.DialogChangeServingBinding
import com.link.play.fit.ai.databinding.LayoutPowerPlateBinding
import com.link.play.fit.ai.ext.d
import com.link.play.fit.ai.store.CloudStore
import com.link.play.fit.ai.store.CloudStore.DOC_CALENDAR_STATUS_LIST_DATA_KEY
import com.link.play.fit.ai.store.CloudStore.DOC_SAVE_FOOD_COLLECT_DATA
import com.link.play.fit.ai.store.CloudStore.deleteList
import com.link.play.fit.ai.ui.dialog.ChangeServingDialog
import com.link.play.fit.ai.ui.main.GlobalViewModel
import com.link.play.fit.ai.ui.main.MainAc
import com.link.play.fit.ai.ui.main.adapter.FoodEditAdapter
import com.link.play.fit.ai.ui.main.adapter.ServingTypeAdapter
import com.link.play.fit.ai.ui.main.saveFood.details.ModifyFoodNameAc
import com.link.play.fit.ai.ui.main.saveFood.details.modifyPage.ModifyCaloriesAc
import com.link.play.fit.ai.ui.main.saveFood.details.modifyPage.ModifyCarbsAc
import com.link.play.fit.ai.ui.main.saveFood.details.modifyPage.ModifyFatsAc
import com.link.play.fit.ai.ui.main.saveFood.details.modifyPage.ModifyProteinAc
import com.link.play.fit.ai.utils.DateEx
import com.link.play.fit.ai.utils.replaceA
import kotlinx.coroutines.launch

//内购-食物编辑详情页
class FoodEditAc : BaseActivity<AcFoodEditBinding>(AcFoodEditBinding::inflate) {

    companion object {
        //intent 中转入的参数名
        const val IntentParamsSearch = "Search"
        const val Bean = "Bean"
    }

    //首页的数据
    private var calendarStatusDataList: MutableList<CalendarStatusData> = mutableListOf()

    lateinit var foodInfo: FoodInfoBean

    //这个页面要用的数据 foodInfo 里的 infoIngredientsbean
    lateinit var ingredients: InfoIngredientsBean

    //当前选择的套餐
    lateinit var servingType: ServingTypeBean

    //serving amont 显示的数量
    var number: Double = 0.0

    //是否保存过  保存过显示删除按钮, 底部按钮改成保存
    private var isSaved = false

    //是从哪里进入的 true 从搜索, false 从首页
    private var isSearch = false


    private val powerPlate: LayoutPowerPlateBinding by lazy {
        LayoutPowerPlateBinding.bind(binding.powerPlate.root)
    }
    private val baseViewModel: GlobalViewModel by lazy {
        GlobalViewModel.getInstance(application)
    }
    val btnAdapter = ServingTypeAdapter()
    val otherNutritionAdapter = FoodEditAdapter()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initParams()
        initView()
        initData()
    }

    fun initParams() {
        try {
            foodInfo = intent.getSerializableExtra(Bean) as FoodInfoBean
            ingredients = foodInfo.ingredients.first()

        } catch (e: Exception) {
            "Invalid Parameter Exception".d()
            finish()
        }
        "ingredients $ingredients".d()
        isSearch = intent.getBooleanExtra(IntentParamsSearch, false)
        //设置默认选中的份量,
        var f = false
        for (i in ingredients.servingTypes) {
            if (ingredients.servingTypeId == i.id) {
                f = true
                servingType = i.deepCopy()
            }
        }
        //如果没有选中份量, 则用第一个
        if (!f) {
            servingType = ingredients.servingTypes.first().deepCopy()
            ingredients.servings = 1.0
        }
        //是修改过的,还是显示原始数据
        when(servingType.metricUnit){
            "g","G"->{
                if (ingredients.servings != 1.0) {
                    number = ingredients.servings * servingType.metricAmount
                } else {
                    number = servingType.metricAmount.toDouble()
                }
            }
            else -> {
                number = servingType.metricAmount.toDouble()
            }
        }
        //添加时间戳,如果没有时间戳就是没有保存过
        if (TextUtils.isEmpty(ingredients.timeMillisencond)) {
            ingredients.timeMillisencond = System.currentTimeMillis().toString()
            isSaved = false
        } else {
            isSaved = true
        }
    }

    fun initView() {
        binding.ivReturn.setOnClickListener {
            finish()
        }

        binding.ivSetting.setOnClickListener {
            binding.deleteFoodText.isVisible = !binding.deleteFoodText.isVisible
        }
        binding.deleteFoodText.setOnClickListener {
            deleteList(
                CloudStore.DOC_RECENTLY_LIST_DATA,
                DateEx.getDayOfMonth(),
                ingredients.timeMillisencond
            )
            baseViewModel.deleteRecentlyData(ingredients.toRecentlyEatenData())
            finish()
        }
        binding.ivSetting.visibility = if (isSaved) View.VISIBLE else View.GONE
        binding.ivCollect.setOnClickListener {
            val f = !binding.ivCollect.isSelected
            //收藏
            if (f) {
                checkData()
                if (binding.btnLog.isEnabled) {
                    val collection = CollectFoodInfoData()
                    collection.build(ingredients.name, number, ingredients, 4, servingType)
                    CloudStore.addToList(
                        DOC_SAVE_FOOD_COLLECT_DATA,
                        date = DOC_SAVE_FOOD_COLLECT_DATA,
                        key = ingredients.timeMillisencond,
                        data = collection
                    )
                    binding.ivCollect.isSelected = true
                }
            } else {
                CloudStore.deleteList(
                    DOC_SAVE_FOOD_COLLECT_DATA,
                    date = DOC_SAVE_FOOD_COLLECT_DATA,
                    key = ingredients.timeMillisencond
                )
                binding.ivCollect.isSelected = false
            }
        }

        binding.recyclerBtn.layoutManager =
            LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
        binding.recyclerBtn.adapter = btnAdapter
        btnAdapter.change = this::switchServingType
        binding.tvFoodName.setOnClickListener {
            lifecycleScope.launch {
                val result = goToAcForResult(ModifyFoodNameAc::class.java) {
                    val str = resources.getString(R.string.tap_to_name)
                    if (binding.tvFoodName.text == str) {
                        putExtra("name", "")
                    } else {
                        putExtra("name", binding.tvFoodName.text.toString())
                    }
                }
                when (result.resultCode) {
                    RESULT_OK -> {
                        val data = result.data?.getStringExtra("result_key").toString()
                        if (TextUtils.isEmpty(data)) {
                            binding.tvFoodName.text = resources.getString(R.string.tap_to_name)
                            ingredients.name = ""
                        } else {
                            binding.tvFoodName.text = data
                            ingredients.name = data
                        }
                        checkData()
                    }
                }
            }
        }
        binding.tvNum.setOnClickListener {
            ChangeServingDialog().apply {
                setData(this@FoodEditAc.number.toInt(), this@FoodEditAc.servingType.label)
                result = { n ->
                    number = n.toDouble()
                    setServingFormat()
                }
            }.show(supportFragmentManager, "numDialog")
        }
        binding.tvSubtractNum.setOnClickListener {
            number--
            if (number < 0) ingredients.servings = 0.0
            setServingFormat()
        }
        binding.tvAddNum.setOnClickListener {
            number++
            setServingFormat()
        }
        powerPlate.rlCalories.setOnClickListener {
            if (calendarStatusDataList.isEmpty()) return@setOnClickListener
            lifecycleScope.launch {
                val result = goToAcForResult(ModifyCaloriesAc::class.java) {
                    putExtra("value", powerPlate.tvCaloriesiNum.text ?: "0")
                    putExtra("bean", calendarStatusDataList.last())
                }
                when (result.resultCode) {
                    RESULT_OK -> {
                        val cal = strToInt(result.data?.getStringExtra("result_key"))
                        ingredients.localCalories = cal.toDouble()
                        checkData()
                    }
                }
            }
        }
        powerPlate.rlProtein.setOnClickListener {
            if (calendarStatusDataList.isEmpty()) return@setOnClickListener
            lifecycleScope.launch {
                val result = goToAcForResult(ModifyProteinAc::class.java) {
                    putExtra("value", powerPlate.tvProteinNum.text.toString().replaceA() ?: "0")
                    putExtra("bean", calendarStatusDataList.last())
                }
                when (result.resultCode) {
                    RESULT_OK -> {
                        val value = strToInt(result.data?.getStringExtra("result_key").toString())
                        ingredients.localProtein = value.toDouble()
                        checkData()
                    }
                }
            }
        }

        powerPlate.rlCarbs.setOnClickListener {
            if (calendarStatusDataList.isEmpty()) return@setOnClickListener
            lifecycleScope.launch {
                val result = goToAcForResult(ModifyCarbsAc::class.java) {
                    putExtra("value", powerPlate.tvCarbsNum.text.toString().replaceA() ?: "0")
                    putExtra("bean", calendarStatusDataList.last())
                }
                when (result.resultCode) {
                    RESULT_OK -> {
                        val value = strToInt(result.data?.getStringExtra("result_key").toString())
                        ingredients.localCarbs = value.toDouble()
                        checkData()
                    }
                }
            }
        }
        powerPlate.rlFats.setOnClickListener {
            if (calendarStatusDataList.isEmpty()) return@setOnClickListener
            lifecycleScope.launch {
                val result = goToAcForResult(ModifyFatsAc::class.java) {
                    putExtra("value", powerPlate.tvFatsNum.text.toString().replaceA() ?: "0")
                    putExtra("bean", calendarStatusDataList.last())
                }
                when (result.resultCode) {
                    RESULT_OK -> {
                        val value = strToInt(result.data?.getStringExtra("result_key").toString())
                        ingredients.localFats = value.toDouble()
                        checkData()
                    }
                }
            }
        }
        binding.recyclerOtherNutrition.layoutManager = LinearLayoutManager(this)
        binding.recyclerOtherNutrition.adapter = otherNutritionAdapter
        if (isSaved) {
            binding.btnLog.text = resources.getString(R.string.save)
        } else {
            binding.btnLog.text = resources.getString(R.string.log)
        }
        binding.btnLog.setOnClickListener {
            val red = ingredients.toRecentlyEatenData()
            CloudStore.addToList(
                CloudStore.DOC_RECENTLY_LIST_DATA,
                DateEx.getDayOfMonth(),
                red.createTime,
                red
            )
            //添加到最近添加的食物列表
            CloudStore.addToList(
                CloudStore.DOC_FOOD_DATABASE_RECENTLY_DATA,
                CloudStore.DOC_FOOD_DATABASE_RECENTLY_DATA,
                ingredients.timeMillisencond,
                foodInfo.apply { select = false }
            )
            if (isSearch) {
                //新建返回首页
                if (isSaved) {
                    goToAc(MainAc::class.java) {
                        addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                    }
                    baseViewModel.updateRecentlyData(red)
                } else {
                    goToAc(MainAc::class.java) {
                        putExtra(
                            "logFood",
                            Gson().toJson(red)
                        )
                        addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                    }
                }
            } else {
                //编辑的需要返回数据
                setResult(RESULT_OK, Intent().apply {
                    putExtra("recentlyEatenData", red)
                })
            }
            finish()
        }
    }

    fun initData() {
        lifecycleScope.launch {
            val coll = CloudStore.getListItem<CollectFoodInfoData>(
                document = DOC_SAVE_FOOD_COLLECT_DATA,
                date = DOC_SAVE_FOOD_COLLECT_DATA,
                key = ingredients.timeMillisencond
            )
            coll?.let {
                binding.ivCollect.isSelected = true
            }
        }
        lifecycleScope.launch {
            calendarStatusDataList = CloudStore.getList<CalendarStatusData>(
                CloudStore.DOC_CALENDAR_STATUS_LIST_DATA, DOC_CALENDAR_STATUS_LIST_DATA_KEY
            ) as MutableList<CalendarStatusData>
        }
        binding.tvFoodName.text = ingredients.name
        btnAdapter.setData(ingredients.servingTypes,servingType)
        setServingFormat()
        checkData()
    }

    //切换份量的按钮
    fun switchServingType(s: ServingTypeBean) {
        servingType = s.deepCopy()
        ingredients.servingTypeId = servingType.id
        ingredients.apply {
            servingTypeId = servingType.id
            calories = servingType.calories
            fats = servingType.fat
            carbs = servingType.carbs
            protein = servingType.protein
            localCalories = 0.0
            localFats = 0.0
            localCarbs = 0.0
            localProtein = 0.0
        }
        number = servingType.metricAmount.toDouble()
        setServingFormat()
        checkData()
    }

    //检察数据规则
    fun checkData() {
        //
        var f = true
        if (TextUtils.isEmpty(ingredients.name)) {
            f = false
        }
        // 能量数值不能全为零
        if (servingType.calories + servingType.carbs +
            servingType.protein + servingType.fat == 0.0
        ) {
            f = false
        }
        binding.btnLog.isEnabled = f
        computeData()
    }

    //参数改之后计算,并且设置回去
    fun computeData() {

        //计算
        if (servingType.metricAmount == 0) servingType.metricAmount = 1
        when (servingType.metricUnit) {
            "g", "G" -> {
                //按照克数计算
                ingredients.servings = number / servingType.metricAmount
            }

            else -> {
                ingredients.servings = number
            }
        }
        //重新设置数据
        if (ingredients.localCalories != 0.0) {
            powerPlate.tvCaloriesiNum.text =
                (ingredients.localCalories * ingredients.servings).toInt().toString()
        } else {
            powerPlate.tvCaloriesiNum.text =
                (servingType.calories * ingredients.servings).toInt().toString()
        }
        if (ingredients.localProtein != 0.0) {
            powerPlate.tvProteinNum.text =
                "${(ingredients.localProtein * ingredients.servings).toInt()}g"
        } else {
            powerPlate.tvProteinNum.text =
                "${(servingType.protein * ingredients.servings).toInt()}g"
        }
        if (ingredients.localCarbs != 0.0) {
            powerPlate.tvCarbsNum.text =
                "${(ingredients.localCarbs * ingredients.servings).toInt()}g"
        } else {
            powerPlate.tvCarbsNum.text = "${(servingType.carbs * ingredients.servings).toInt()}g"
        }
        if (ingredients.localFats != 0.0) {
            powerPlate.tvFatsNum.text = "${(ingredients.localFats * ingredients.servings).toInt()}g"
        } else {
            powerPlate.tvFatsNum.text = "${(servingType.fat * ingredients.servings).toInt()}g"
        }
        otherNutritionAdapter.setData(ingredients.servings, servingType)
    }

    private fun setServingFormat() {
        when (servingType.label) {
            "g", "G" -> {
                binding.tvNum.text =
                    "${number.toInt()}${servingType.metricUnit}"
            }

            else -> {
                binding.tvNum.text = number.toInt().toString()
            }
        }
        runCatching {
            if (number.toInt() == servingType.metricAmount) {
                binding.tvServingAmount.text = resources.getString(R.string.serving_amount)
            } else {
                binding.tvServingAmount.text = resources.getString(R.string.serving_amount) +
                        " x" +
                        binding.tvNum.text
            }
        }
        checkData()
    }

    private fun strToInt(str: String?): Int {
        if (TextUtils.isEmpty(str)) return 0
        try {
            return str!!.toInt()
        } catch (e: Exception) {
            return 0
        }
    }
}